package com.mlh.dp.买卖股票的最佳时机;

/**
 * @author 缪林辉
 * @date 2024/4/27 10:59
 * @DESCRIPTION
 */
// 给定一个整数数组prices，其中第  prices[i] 表示第 i 天的股票价格
// 设计一个算法计算出最大利润。在满足以下约束条件下，你可以尽可能地完成更多的交易（多次买卖一支股票）:
// 卖出股票后，你无法在第二天买入股票 (即冷冻期为 1 天)。
// 注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。
public class 最佳买卖股票时机含冷冻期 {
    //看代码随想录写出
    // 具体可以区分出如下四个状态：
    // 状态一：持有股票状态（今天买入股票，或者是之前就买入了股票然后没有操作，一直持有）
    // 不持有股票状态，这里就有两种卖出股票状态
    // 状态二：保持卖出股票的状态（两天前就卖出了股票，度过一天冷冻期。或者是前几天就是卖出股票状态，一直没操作）
    // 状态三：今天卖出股票
    // 状态四：今天为冷冻期状态，但冷冻期状态不可持续，只有一天！

    //达到买入股票状态（状态一）即：dp[i][0]，有两个具体操作：
    // 操作一：前一天就是持有股票状态（状态一），dp[i][0] = dp[i - 1][0]
    // 操作二：今天买入了，有两种情况
    // 前一天是冷冻期（状态四），dp[i - 1][3] - prices[i]
    // 前一天是保持卖出股票的状态（状态二），dp[i - 1][1] - prices[i]
    // 那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);

    // 达到保持卖出股票状态（状态二）即：dp[i][1]，有两个具体操作：
    // 操作一：前一天就是状态二
    // 操作二：前一天是冷冻期（状态四）
    // dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);

    // 达到今天就卖出股票状态（状态三），即：dp[i][2] ，只有一个操作：
    // 昨天一定是持有股票状态（状态一），今天卖出
    // 即：dp[i][2] = dp[i - 1][0] + prices[i];

    // 达到冷冻期状态（状态四），即：dp[i][3]，只有一个操作：
    // 昨天卖出了股票（状态三）
    // dp[i][3] = dp[i - 1][2];
    public int method1(int[] prices) {
        if(prices.length<2){
            return 0;
        }
        int[]dp=new int[4];
        //初始化
        dp[0]=-prices[0];// 持股票
        for (int i = 1; i < prices.length; i++) {
            // dp[i][0] = Math.max(dp[i - 1][0], Math.max(dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]));
            // dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][3]);
            // dp[i][2] = dp[i - 1][0] + prices[i];
            // dp[i][3] = dp[i - 1][2];
            //上面是二维数组  这里优化成滚动数组
            int temp=dp[0];
            dp[0] = Math.max(dp[0], Math.max(dp[3] - prices[i], dp[1] - prices[i]));
            dp[1] = Math.max(dp[1], dp[3]);
            dp[3] = dp[2];
            dp[2] = temp + prices[i];
        }
        return Math.max(dp[3], Math.max(dp[1], dp[2]));
    }
}
